/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2021-02-27 16:57:13
 * @LastEditors: ding-cx
 * @LastEditTime: 2021-04-02 11:55:22
 * @Description: file content
 */

import { Service } from "egg";
import * as _ from "lodash";
import { sysMenusInterface } from "../../model/sys/menus";

import { Op } from "sequelize";

/**
 *系统、 菜单管理服务功能。
 *
 * @export
 * @class MenusService
 * @extends {Service}
 */
export default class MenusService extends Service {
  /**
   *创建前端路由表
   *
   * @memberof MenusService
   */
  async createFrontEndRoute(isPermission = true) {
    let wherePerm = {};
    // 如果是admin用户，则拥有所有权。不进行控制。
    if (!isPermission || this.ctx.loginUserInfo.name === "admin") {
      wherePerm = {};
    } else {
      // 菜单权限id列表
      const permMenuList = await this.ctx.service.sys.user.getUserPermissionById(
        this.ctx.loginUserInfo.uid
      );
      // console.log(permMenuList);
      wherePerm = { id: permMenuList };
    }
    // console.log(wherePerm);

    const menuList = await this.ctx.model.Sys.Menus.findAll({
      raw: false,
      where: {
        ...wherePerm,
      },
      order: [
        ["parent_menu_id", "asc"],
        // ["id", "asc"],
        ["order", "asc"],
      ],
    });

    // console.log(menuList);

    function createRouteItem(item: sysMenusInterface, isRoot = false) {
      return {
        route_id: item.id,
        component: item.component,
        path: isRoot ? "/" + item.path : item.path,
        name: item.component_name || item.path,//路由name优先使用component_name
        hidden: item.is_hidden,
        alwaysShow: item.always_show,
        redirect: item.redirect,
        title: item.title,
        meta: {
          title: item.title,
          icon: item.icon,
          noCache: item.no_cache || false,
          affix: item.affix,
          breadcrumb: item.breadcrumb,
          activeMenu: item.active_menu,
          menu_id: item.id,
        },
        trees: [] as number[],

        //   children:[]
      };
    }
    // console.log(menuList);
    // 将嵌套的路由对象打平的引用保存起来。
    const menuObjList = {};

    const routeList: any[] = [];
    menuList.forEach((item) => {
      // 根菜单处理
      if (item.parent_menu_id === 0) {
        const itemRoute = createRouteItem(item, true);
        itemRoute.trees = [item.id]; //把树路径id挂在每个node上。
        routeList.push(itemRoute);
        //以当前项的id作为键，暂存索引在临时对象中以便后续取用。
        menuObjList[item.id] = itemRoute;
      } else {
        //   如果有上级菜单信息，才能嵌套。
        const parentObj = menuObjList[item.parent_menu_id];
        if (parentObj) {
          const itemRoute = createRouteItem(item, false);
          itemRoute.trees = [...parentObj.trees, item.id]; //把树路径id挂在每个node上。

          if (!parentObj.children) {
            parentObj["children"] = [];
          }
          parentObj.children.push(itemRoute);
          menuObjList[item.id] = itemRoute;
        }
      }
    });

    return routeList;
  }

  /**
   *根据上级菜单id查询列表
   *
   * @param {number} [parent_menu_id=0] 上级菜单的id
   * @memberof MenusService
   */
  async getRouteListByParentId(parent_menu_id: number = 0) {
    const menuModel = this.ctx.model.Sys.Menus;
    const data = await menuModel.findAndCountAll({
      raw: true,
      where: {
        parent_menu_id,
      },
    });
    // console.log(data);
    return data;
  }

  /**
   *左侧树点击获取当前及所有后代菜单的列表
   *
   * @param {number} [parent_menu_id=0] 上级菜单的id
   * @memberof MenusService
   */
  async getRouteListByIdList(
    idList: number[] = [],
    page: [number, number] = [20, 0]
  ) {
    const menuModel = this.ctx.model.Sys.Menus;

    const data = await menuModel.findAndCountAll({
      raw: false,
      where: {
        id: {
          [Op.in]: idList,
        },
      },
      limit: page[0],
      offset: page[1],
      attributes: {
        include: [
          [
            (this.ctx.model.Sequelize.col(
              "parent_menu.title"
            ) as unknown) as string,
            "parent_title",
          ],
        ],
      },
      include: {
        model: menuModel,
        as: "parent_menu",
        required: false, //inner join 改为outner join
        where: {},
        attributes: [],
      },
    });
    // console.log(data);
    return data;
  }
}
